﻿using MLSMooc.Helper;
using MLSMooc.Session;
using MLSMooc.Session.Implement;
using MLSMooc.Session.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace MLSMooc.Filters
{
    public class SPSExceptionFilter : IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            //记录并处理异常
            SessionUser sessionUser = SessionUserService.GetInstance().DeSerializeDecrypt(SessionBaseOpt.GetSessionState<string>(ConstantHelper.USER, string.Empty));
            int userId = sessionUser == null ? 0 : sessionUser.Id;

            try
            {
                //设置该异常已被处理，不再向顶层IIS抛出
                filterContext.ExceptionHandled = true;
                //禁止IIS向页面抛错
                filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

                //响应码
                filterContext.HttpContext.Response.StatusCode = 500;

                //根据请求方法设置响应体
                if (filterContext.HttpContext.Request.RequestType.ToLower().Equals("get"))
                {
                    //get请求的错误响应
                    filterContext.Result = new RedirectResult($"{ConstantHelper.VIRTUAL_PATH}/Login/Problem/500");
                }
                else
                {
                    //post请求的错误响应
                    filterContext.Result = new ContentResult()
                    {
                        ContentType = "application/json",
                        ContentEncoding = Encoding.UTF8,
                        Content = SerializeHelper.SerializeJson(Enum.GetName(typeof(HttpCode), 500))
                    };
                }

                //写入文件
                ExceptionOutPrint(null, filterContext, userId);
            }
            catch (Exception ex)
            {
                ExceptionOutPrint(ex, filterContext, userId);
            }

        }

        private void ExceptionOutPrint(Exception ex, ExceptionContext filterContext, int userId = 0)
        {
            //在项目的文件夹下面的Log文件夹中写入新的日志信息，以文本的方式记录
            StringBuilder sb = new StringBuilder();
            if (ex != null)
            {
                sb.AppendLine("------------------Catch 导致不能写入数据库的异常-----------------");
                sb.AppendLine($"Message::::::::::{ex.Message}");
                sb.AppendLine($"Source::::::::::{ex.Source}");
                sb.AppendLine($"StackTrace::::::::::{ex.StackTrace}");
                sb.AppendLine($"DateTime::::::::::{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff")}");
                sb.AppendLine();
            }

            sb.AppendLine("------------------ExceptionFilter拦截的的异常-----------------");
            sb.AppendLine($"UserId:::::::::{userId}");
            sb.AppendLine($"IP:::::::::{filterContext.RequestContext.HttpContext.Request.UserHostAddress}");
            sb.AppendLine($"Agent:::::::::{filterContext.RequestContext.HttpContext.Request.UserAgent}");
            sb.AppendLine($"Cotroller:::::::::{ filterContext.RouteData.Values["controller"]?.ToString()}");
            sb.AppendLine($"Action:::::::::{ filterContext.RouteData.Values["action"]?.ToString()}");
            sb.AppendLine($"Message::::::::::{filterContext.Exception.Message}");
            sb.AppendLine($"Source::::::::::{filterContext.Exception.Source}");
            sb.AppendLine($"StackTrace::::::::::{filterContext.Exception.StackTrace}");
            sb.AppendLine($"DateTime::::::::::{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff")}");

            string folder = HttpContext.Current.Server.MapPath(@"~/ExceptionInfo");
            if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);

            string path = folder + "\\" + CommonHelper.GetRandomFileNm() + ".txt";
            using (FileStream fs = new FileStream(path, FileMode.Create))
            {
                StreamWriter sw = new StreamWriter(fs);
                sw.Write(sb.ToString());
                sw.Flush();
                sw.Close();
            }
        }
    }
}